// Copyright (C) 2020-2022 Intel Corporation
// Copyright (C) 2022-2024 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT

import React, { useEffect, useState } from 'react';
import { Routes, Route, Navigate, useLocation } from 'react-router-dom-v5-compat';

import { Spin, Layout, message } from 'antd';

import LoginPage from 'layouts/LoginPage';
import GlobalErrorBoundary from 'components/global-error-boundary/global-error-boundary';
import ShortcutsDialog from 'components/shortcuts-dialog/shortcuts-dialog';
import DataBasePageComponent from 'components/data-base/data-base';
import TaskManagerPageComponent from 'components/task-manager/task-manager';
import TasksPageContainer from 'containers/tasks-page/tasks-page';
import { ShortcutsContextProvider } from 'components/shortcuts.context';

import AnnotationPageContainer from 'containers/annotation-page/annotation-page';
import { NotificationsState, PluginsState } from 'reducers';
import '../styles.scss';
import PageLayout from 'layouts/index';
import UserCenter from 'pages/home/userCenter/Index';
import RoleManager from 'pages/system/role/roleManage/Index';
import UserManager from 'pages/system/user/userManage/Index';
import Password from 'pages/home/userCenter/Password';
import OrgPage from 'pages/system/platform/org/Index';
import MenuManagePage from 'pages/system/platform/menu/Index';

import useUserStore, { useTokenStore } from 'store/user';
import { formatMenus } from 'router';

import MENUS from 'constant/menu';
import useLogin from 'hooks/useLogin';
import { getLoginUserInfo, queryUserAuthedMenuTree } from 'apis/common';

interface CVATAppProps {
    loadFormats: () => void;
    loadAbout: () => void;
    verifyAuthenticated: () => void;
    loadUserAgreements: () => void;
    initPlugins: () => void;
    initModels: () => void;
    resetErrors: () => void;
    resetMessages: () => void;
    loadOrganization: () => void;
    initInvitations: () => void;
    initRequests: () => void;
    loadServerAPISchema: () => void;
    userInitialized: boolean;
    userFetching: boolean;
    organizationFetching: boolean;
    organizationInitialized: boolean;
    pluginsInitialized: boolean;
    pluginsFetching: boolean;
    modelsInitialized: boolean;
    modelsFetching: boolean;
    formatsInitialized: boolean;
    formatsFetching: boolean;
    aboutInitialized: boolean;
    aboutFetching: boolean;
    userAgreementsFetching: boolean;
    userAgreementsInitialized: boolean;
    notifications: NotificationsState;
    user: any;
    isModelPluginActive: boolean;
    pluginComponents: PluginsState['components'];
    invitationsFetching: boolean;
    invitationsInitialized: boolean;
    requestsFetching: boolean;
    requestsInitialized: boolean;
    serverAPISchemaFetching: boolean;
    serverAPISchemaInitialized: boolean;
    isPasswordResetEnabled: boolean;
    isRegistrationEnabled: boolean;
}

export default function App(props: CVATAppProps) {
    const location = useLocation();
    const [list, setList] = useState<any[]>([]);
    const {
        initPlugins,
        initModels,
        pluginsInitialized,
        pluginsFetching,
        modelsInitialized,
        modelsFetching,
        isModelPluginActive,
    } = props;

    const { updateUserInfo, updateMenu, userInfo } = useUserStore();
    const { currentTenant, setCurrentTenant } = useTokenStore();
    const { token, handleLogin } = useLogin();
    const [isLoad, setIsLoad] = useState<boolean>(false);

    const beforeIntoApp = (res: API.LoginUserInfoResponseType) => {
        updateUserInfo(res);
        if (res?.tenants?.length === 1) {
            setCurrentTenant(res?.tenants?.[0]?.tenantId || '');
        } else if (res?.tenants?.length) {
            // 需要选择
        }
    };

    const getUserInfo = async () => {
        const res = await getLoginUserInfo();
        beforeIntoApp(res);
    };

    const getMenuData = async () => {
        const components = {} as any;
        try {
            const res = await queryUserAuthedMenuTree();
            console.log('res', res);
            const { menuList, routerList, menuMap, menuPaths, firstPath, subMenuPath, actionPerms } = formatMenus(
                res.menuTree?.children || MENUS,
                components,
            );
            updateMenu(menuList, menuMap, menuPaths, firstPath, subMenuPath, actionPerms);
            const arr = [];
            routerList.forEach((v) => {
                arr.push(v.path);
                if (v.children && v.children.length) {
                    v.children.forEach((item) => {
                        arr.push(item.path);
                    });
                }
            });
            setList(arr);
            console.log('list', arr);
            console.log(
                'menuList, menuMap, menuPaths, firstPath, subMenuPath, actionPerms',
                menuList,
                menuMap,
                menuPaths,
                firstPath,
                subMenuPath,
                actionPerms,
            );
            setIsLoad(true);
        } catch (error) {
            console.error(error);
            setIsLoad(true);
        }
    };

    useEffect(() => {
        if (currentTenant) {
            getMenuData();
        }
    }, [currentTenant]);

    useEffect(() => {
        // 是否登录
        if (!token) {
            handleLogin();
        } else {
            getUserInfo();
        }
    }, [token]);

    useEffect(() => {
        message.config({
            top: 300,
            maxCount: 3,
        });
    }, []);

    useEffect(() => {
        if (isModelPluginActive && !modelsInitialized && !modelsFetching && token) {
            initModels();
        }
    }, [isModelPluginActive, modelsInitialized, modelsFetching, token]);

    useEffect(() => {
        if (!pluginsInitialized && !pluginsFetching && token) {
            initPlugins();
        }
    }, [pluginsInitialized, pluginsFetching, token]);

    const { pluginComponents } = props;
    const routesToRender = pluginComponents.router.map(({ component: Component }) => Component());

    if (!!token && Number(userInfo?.restPasswdTag) === 1) {
        return (
            <Password
                visible
                title='设置密码'
                modalProps={{
                    closeIcon: null,
                }}
                successCallback={getUserInfo}
                hideOldPassword
            />
        );
    }
    if (token) {
        if (!isLoad) {
            return <Spin size='large' fullscreen />;
        }
        return (
            <GlobalErrorBoundary>
                <ShortcutsContextProvider>
                    <Layout>
                        {/* <Header /> */}
                        <Layout.Content style={{ height: '100%' }}>
                            <ShortcutsDialog />
                            <Routes>
                                <Route path='login' element={<LoginPage />} />
                                <Route path='/' element={<PageLayout />}>
                                    {list.includes('/tasks/:tid/jobs/:jid/subtask/:sid/action/:action') ? (
                                        <Route
                                            path='/tasks/:tid/jobs/:jid/subtask/:sid/action/:action'
                                            element={<AnnotationPageContainer />}
                                        />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/database') ? (
                                        <Route path='/database' element={<DataBasePageComponent />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/taskManager') ? (
                                        <Route path='/taskManager' element={<TaskManagerPageComponent />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/system/roleManage') ? (
                                        <Route path='/system/roleManage' element={<RoleManager parentNode={null} />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/system/userManage') ? (
                                        <Route path='/system/userManage' element={<UserManager parentNode={null} />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/system/org') ? (
                                        <Route path='/system/org' element={<OrgPage />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/system/menuManage') ? (
                                        <Route path='/system/menuManage' element={<MenuManagePage />} />
                                    ) : (
                                        ''
                                    )}
                                    {list.includes('/system/menuManage') ? (
                                        <Route path='/userCenter' element={<UserCenter />} />
                                    ) : (
                                        ''
                                    )}
                                </Route>
                                {routesToRender}
                            </Routes>
                            {/* eslint-disable-next-line */}
                            <a id='downloadAnchor' target='_blank' style={{ display: 'none' }} download />
                        </Layout.Content>
                    </Layout>
                </ShortcutsContextProvider>
            </GlobalErrorBoundary>
        );
    }

    const loginRedirect = location.pathname.length > 1 ? `/login?next=${location.pathname}` : '/login';

    return (
        <GlobalErrorBoundary>
            <Routes>
                <Route path='login' element={<LoginPage />} />

                {routesToRender}

                <Route path='*' element={<Navigate to={loginRedirect} replace />} />
            </Routes>
        </GlobalErrorBoundary>
    );
}
